% visualize_flashattention_cases.m
% 专门为FlashAttention_Case0和FlashAttention_Case1的帕累托解可视化脚本
% 数据来源：MATLAB优化结果

clear; clc; close all;

%% 设置
fprintf('=== FlashAttention双案例帕累托解可视化分析 ===\n\n');

% 设置工作目录和数据路径
base_dir = 'E:\GMCM_2025_A\problem2and3pro\Problem3_MATLAB';

% FlashAttention案例列表和显示名称
cases = {'FlashAttention_Case0', 'FlashAttention_Case1'};
case_display_names = {'FlashAttention-Case0', 'FlashAttention-Case1'};

% 专业配色方案 - 与参考脚本一致
colors = [
    0.0 0.3 0.8;    % FlashAttention_Case0 - 深蓝色
    1.0 0.5 0.0;    % FlashAttention_Case1 - 橙色
];

markers = {'o', 's'};
line_styles = {'-', '--'};

% 创建输出目录
output_dir = fullfile(base_dir, 'FlashAttention_Comparison');
if ~exist(output_dir, 'dir')
    mkdir(output_dir);
end

%% 数据读取与分析
fprintf('1. 读取FlashAttention帕累托解数据...\n');

pareto_data = {};
data_summary = {};

for i = 1:length(cases)
    case_name = cases{i};
    csv_file = fullfile(base_dir, case_name, [case_name '_pareto_solutions.csv']);
    
    fprintf('   检查文件: %s\n', csv_file);
    if exist(csv_file, 'file')
        fprintf('   ✓ 文件存在，正在读取...\n');
        data = readtable(csv_file);
        pareto_data{i} = data;
        
        % 数据分析
        unique_solutions = unique([data.time, data.spill], 'rows');
        strategies = unique(data.strategy_type);
        
        fprintf('   %s:\n', case_name);
        fprintf('     - 总解数: %d\n', height(data));
        fprintf('     - 唯一解: %d (多样性: %.1f%%)\n', size(unique_solutions,1), size(unique_solutions,1)/height(data)*100);
        fprintf('     - 策略类型: %s\n', strjoin(strategies, ', '));
        fprintf('     - Time范围: [%.0f, %.0f]\n', min(data.time), max(data.time));
        fprintf('     - Spill范围: [%.0f, %.0f]\n', min(data.spill), max(data.spill));
        fprintf('     - Threshold范围: [%.2f, %.2f]\n', min(data.min_farthest_use_threshold), max(data.min_farthest_use_threshold));
        
        % 保存数据摘要
        data_summary{i} = struct(...
            'case_name', case_name, ...
            'total_solutions', height(data), ...
            'unique_solutions', size(unique_solutions,1), ...
            'strategies', strategies, ...
            'time_range', [min(data.time), max(data.time)], ...
            'spill_range', [min(data.spill), max(data.spill)], ...
            'threshold_range', [min(data.min_farthest_use_threshold), max(data.min_farthest_use_threshold)] ...
        );
        
        fprintf('   ✓ 数据读取完成\n\n');
    else
        fprintf('   ✗ 文件不存在: %s\n', csv_file);
        pareto_data{i} = [];
    end
end

%% 绘图1: 帕累托前沿对比
fprintf('2. 生成帕累托前沿对比图...\n');

figure('Position', [100, 100, 1000, 700], 'Color', 'white');
hold on;

legend_entries = {};
legend_handles = [];

for i = 1:length(cases)
    if ~isempty(pareto_data{i})
        data = pareto_data{i};
        
        % 绘制散点 - 与参考脚本一致的样式
        h = scatter(data.time, data.spill, 120, colors(i,:), ...
                   'Marker', markers{i}, 'MarkerEdgeColor', 'black', 'LineWidth', 2.0);
        
        legend_handles = [legend_handles, h];
        legend_entries{end+1} = sprintf('%s (%d解)', case_display_names{i}, height(data));
        
        % 如果有多个点，连接帕累托前沿
        if height(data) > 1
            % 排序并连接
            [~, idx] = sort(data.time);
            sorted_data = data(idx, :);
            try
                plot(sorted_data.time, sorted_data.spill, '--', 'Color', colors(i,:), ...
                     'LineWidth', 2.0, 'Alpha', 0.7);
            catch
                plot(sorted_data.time, sorted_data.spill, '--', 'Color', colors(i,:), ...
                     'LineWidth', 2.0);
            end
        end
    end
end

% 图表装饰 - 与参考脚本一致
xlabel('执行时间 (cycles)', 'FontSize', 14, 'FontWeight', 'bold', 'Color', 'black');
ylabel('额外数据搬运量 (bytes)', 'FontSize', 14, 'FontWeight', 'bold', 'Color', 'black');
title('FlashAttention案例帕累托前沿对比', 'FontSize', 16, 'FontWeight', 'bold', 'Color', 'black');

if ~isempty(legend_handles)
    legend(legend_handles, legend_entries, 'Location', 'best', 'FontSize', 12, ...
           'EdgeColor', [0.5 0.5 0.5], 'TextColor', 'black', 'Color', 'white');
end

grid on;
set(gca, 'FontSize', 12, 'GridColor', 'black', 'GridAlpha', 0.3, 'LineWidth', 1.5, ...
    'XColor', 'black', 'YColor', 'black', 'Color', 'white', 'Box', 'on');

% 保存图片 - 与参考脚本一致的保存方式
set(gcf, 'Color', 'white', 'InvertHardcopy', 'off');
pareto_comparison_file = fullfile(output_dir, 'flashattention_pareto_comparison.png');
print(gcf, pareto_comparison_file, '-dpng', '-r300');
saveas(gcf, strrep(pareto_comparison_file, '.png', '.fig'));
fprintf('   ✓ 帕累托前沿对比图已保存: %s\n', pareto_comparison_file);

%% 绘图2: 数据统计对比
fprintf('3. 生成数据统计对比图...\n');

figure('Position', [150, 150, 1200, 800], 'Color', 'white');

% 2x2子图布局
subplot(2, 2, 1);
% Time范围对比
time_mins = [];
time_maxs = [];
case_labels = {};

for i = 1:length(data_summary)
    if ~isempty(data_summary{i})
        time_mins(end+1) = data_summary{i}.time_range(1);
        time_maxs(end+1) = data_summary{i}.time_range(2);
        case_labels{end+1} = data_summary{i}.case_name;
    end
end

if ~isempty(time_mins)
    x_pos = 1:length(time_mins);
    bar_width = 0.35;
    
    bar(x_pos - bar_width/2, time_mins, bar_width, 'FaceColor', [0.3 0.6 0.9], 'DisplayName', 'Min Time');
    hold on;
    bar(x_pos + bar_width/2, time_maxs, bar_width, 'FaceColor', [0.9 0.3 0.6], 'DisplayName', 'Max Time');
    
    set(gca, 'XTick', x_pos, 'XTickLabel', case_labels, 'FontSize', 10);
    ylabel('执行时间', 'FontSize', 12);
    title('Time范围对比', 'FontSize', 13, 'FontWeight', 'bold');
    legend('Location', 'best');
    grid on; grid minor;
end

% Spill范围对比
subplot(2, 2, 2);
spill_mins = [];
spill_maxs = [];

for i = 1:length(data_summary)
    if ~isempty(data_summary{i})
        spill_mins(end+1) = data_summary{i}.spill_range(1);
        spill_maxs(end+1) = data_summary{i}.spill_range(2);
    end
end

if ~isempty(spill_mins)
    x_pos = 1:length(spill_mins);
    bar_width = 0.35;
    
    bar(x_pos - bar_width/2, spill_mins, bar_width, 'FaceColor', [0.3 0.9 0.6], 'DisplayName', 'Min Spill');
    hold on;
    bar(x_pos + bar_width/2, spill_maxs, bar_width, 'FaceColor', [0.9 0.6 0.3], 'DisplayName', 'Max Spill');
    
    set(gca, 'XTick', x_pos, 'XTickLabel', case_labels, 'FontSize', 10);
    ylabel('溢出量', 'FontSize', 12);
    title('Spill范围对比', 'FontSize', 13, 'FontWeight', 'bold');
    legend('Location', 'best');
    grid on; grid minor;
end

% 解数量对比
subplot(2, 2, 3);
solution_counts = [];

for i = 1:length(data_summary)
    if ~isempty(data_summary{i})
        solution_counts(end+1) = data_summary{i}.total_solutions;
    end
end

if ~isempty(solution_counts)
    bar(solution_counts, 'FaceColor', [0.6 0.3 0.9]);
    set(gca, 'XTickLabel', case_labels, 'FontSize', 10);
    ylabel('解的数量', 'FontSize', 12);
    title('解数量对比', 'FontSize', 13, 'FontWeight', 'bold');
    grid on; grid minor;
    
    % 在柱状图上添加数值标签
    for i = 1:length(solution_counts)
        text(i, solution_counts(i) + max(solution_counts)*0.02, ...
             sprintf('%d', solution_counts(i)), ...
             'HorizontalAlignment', 'center', 'FontSize', 11, 'FontWeight', 'bold');
    end
end

% Threshold范围对比
subplot(2, 2, 4);
threshold_mins = [];
threshold_maxs = [];

for i = 1:length(data_summary)
    if ~isempty(data_summary{i})
        threshold_mins(end+1) = data_summary{i}.threshold_range(1);
        threshold_maxs(end+1) = data_summary{i}.threshold_range(2);
    end
end

if ~isempty(threshold_mins)
    x_pos = 1:length(threshold_mins);
    bar_width = 0.35;
    
    bar(x_pos - bar_width/2, threshold_mins, bar_width, 'FaceColor', [0.9 0.9 0.3], 'DisplayName', 'Min Threshold');
    hold on;
    bar(x_pos + bar_width/2, threshold_maxs, bar_width, 'FaceColor', [0.3 0.9 0.9], 'DisplayName', 'Max Threshold');
    
    set(gca, 'XTick', x_pos, 'XTickLabel', case_labels, 'FontSize', 10);
    ylabel('Threshold值', 'FontSize', 12);
    title('Threshold范围对比', 'FontSize', 13, 'FontWeight', 'bold');
    legend('Location', 'best');
    grid on; grid minor;
end

% 总标题
sgtitle('FlashAttention双案例数据统计对比', 'FontSize', 16, 'FontWeight', 'bold');

% 保存统计对比图
stats_comparison_file = fullfile(output_dir, 'flashattention_stats_comparison.png');
saveas(gcf, stats_comparison_file);
fprintf('   ✓ 数据统计对比图已保存: %s\n', stats_comparison_file);

%% 绘图3: 参数权重分布对比
fprintf('4. 生成参数权重分布对比图...\n');

figure('Position', [200, 200, 1200, 600], 'Color', 'white');

subplot(1, 3, 1);
% w_use分布
hold on;
for i = 1:length(cases)
    if ~isempty(pareto_data{i})
        data = pareto_data{i};
        histogram(data.w_use, 'FaceColor', colors(i,:), 'FaceAlpha', 0.7, ...
                  'EdgeColor', 'black', 'DisplayName', case_display_names{i});
    end
end
xlabel('w\_use权重', 'FontSize', 12);
ylabel('频次', 'FontSize', 12);
title('w\_use分布对比', 'FontSize', 13, 'FontWeight', 'bold');
legend('Location', 'best');
grid on; grid minor;

subplot(1, 3, 2);
% w_vol分布
hold on;
for i = 1:length(cases)
    if ~isempty(pareto_data{i})
        data = pareto_data{i};
        histogram(data.w_vol, 'FaceColor', colors(i,:), 'FaceAlpha', 0.7, ...
                  'EdgeColor', 'black', 'DisplayName', case_display_names{i});
    end
end
xlabel('w\_vol权重', 'FontSize', 12);
ylabel('频次', 'FontSize', 12);
title('w\_vol分布对比', 'FontSize', 13, 'FontWeight', 'bold');
legend('Location', 'best');
grid on; grid minor;

subplot(1, 3, 3);
% w_vic分布
hold on;
for i = 1:length(cases)
    if ~isempty(pareto_data{i})
        data = pareto_data{i};
        histogram(data.w_vic, 'FaceColor', colors(i,:), 'FaceAlpha', 0.7, ...
                  'EdgeColor', 'black', 'DisplayName', case_display_names{i});
    end
end
xlabel('w\_vic权重', 'FontSize', 12);
ylabel('频次', 'FontSize', 12);
title('w\_vic分布对比', 'FontSize', 13, 'FontWeight', 'bold');
legend('Location', 'best');
grid on; grid minor;

% 总标题
sgtitle('FlashAttention双案例参数权重分布对比', 'FontSize', 16, 'FontWeight', 'bold');

% 保存权重分布图
weights_distribution_file = fullfile(output_dir, 'flashattention_weights_distribution.png');
saveas(gcf, weights_distribution_file);
fprintf('   ✓ 参数权重分布对比图已保存: %s\n', weights_distribution_file);

%% 生成综合报告
fprintf('5. 生成FlashAttention双案例分析报告...\n');

report_file = fullfile(output_dir, 'flashattention_analysis_report.txt');
fid = fopen(report_file, 'w');

fprintf(fid, '=== FlashAttention双案例帕累托解分析报告 ===\n');
fprintf(fid, '生成时间: %s\n\n', datestr(now, 'yyyy-mm-dd HH:MM:SS'));

fprintf(fid, '1. 案例概览:\n');
for i = 1:length(data_summary)
    if ~isempty(data_summary{i})
        s = data_summary{i};
        fprintf(fid, '   %s:\n', s.case_name);
        fprintf(fid, '     - 解的总数: %d\n', s.total_solutions);
        fprintf(fid, '     - 唯一解数: %d\n', s.unique_solutions);
        fprintf(fid, '     - Time范围: [%.0f, %.0f]\n', s.time_range(1), s.time_range(2));
        fprintf(fid, '     - Spill范围: [%.0f, %.0f]\n', s.spill_range(1), s.spill_range(2));
        fprintf(fid, '     - Threshold范围: [%.2f, %.2f]\n', s.threshold_range(1), s.threshold_range(2));
        fprintf(fid, '\n');
    end
end

fprintf(fid, '2. 对比分析:\n');
if length(data_summary) == 2 && ~isempty(data_summary{1}) && ~isempty(data_summary{2})
    s1 = data_summary{1};
    s2 = data_summary{2};
    
    fprintf(fid, '   Time差异:\n');
    fprintf(fid, '     - Case0平均Time: %.0f\n', mean(s1.time_range));
    fprintf(fid, '     - Case1平均Time: %.0f\n', mean(s2.time_range));
    fprintf(fid, '     - 相对差异: %.1f%%\n', abs(mean(s2.time_range) - mean(s1.time_range)) / mean(s1.time_range) * 100);
    
    fprintf(fid, '   Spill差异:\n');
    fprintf(fid, '     - Case0平均Spill: %.0f\n', mean(s1.spill_range));
    fprintf(fid, '     - Case1平均Spill: %.0f\n', mean(s2.spill_range));
    fprintf(fid, '     - 相对差异: %.1f%%\n', abs(mean(s2.spill_range) - mean(s1.spill_range)) / mean(s1.spill_range) * 100);
    
    fprintf(fid, '   解的数量差异:\n');
    fprintf(fid, '     - Case0: %d解\n', s1.total_solutions);
    fprintf(fid, '     - Case1: %d解\n', s2.total_solutions);
end

fprintf(fid, '\n3. 生成的图表文件:\n');
fprintf(fid, '   - flashattention_pareto_comparison.png\n');
fprintf(fid, '   - flashattention_stats_comparison.png\n');
fprintf(fid, '   - flashattention_weights_distribution.png\n');

fclose(fid);

fprintf('   ✓ 分析报告已保存: %s\n', report_file);

%% 完成
fprintf('\n=== FlashAttention双案例可视化分析完成 ===\n');
fprintf('输出目录: %s\n', output_dir);
fprintf('共生成 3 个可视化图表和 1 个分析报告。\n\n');

% 显示数据摘要
fprintf('数据摘要:\n');
for i = 1:length(data_summary)
    if ~isempty(data_summary{i})
        s = data_summary{i};
        fprintf('  %s: %d解, Time=[%.0f,%.0f], Spill=[%.0f,%.0f]\n', ...
                s.case_name, s.total_solutions, s.time_range(1), s.time_range(2), ...
                s.spill_range(1), s.spill_range(2));
    end
end
